package com.winit.openapi.tools.builder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.oms.spi.outbound.vo.order.OutboundOrderPalletDetailVo;
import com.winit.oms.spi.v2.tools.request.ProductRecommendRequestParams;
import com.winit.oms.spi.v2.tools.request.RequestParamsMerchandises;
import com.winit.oms.spi.v2.tools.request.RequestParamsParcels;
import com.winit.oms.spi.v2.tools.request.RequestParamsReceiveAddress;
import com.winit.oms.spi.v2.tools.request.RequestParamsVAS;
import com.winit.oms.spi.v2.tools.request.RequestParamsVASAttrs;
import com.winit.oms.spi.v2.tools.result.ProductRecommendProductResult;
import com.winit.oms.spi.v2.tools.result.ResultWinitProduct;
import com.winit.oms.spi.vo.v2.order.VasAttributeInfo;
import com.winit.oms.spi.vo.v2.order.VasInfo;
import com.winit.oms.spi.vo.v2.response.FeeDetailResult;
import com.winit.oms.spi.vo.v2.response.QueryUsableWinitProductResult;
import com.winit.oms.spi.vo.v2.response.Response;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.exception.ApiException;

/**
 * 海外仓入库单 提货验货构造器
 * 
 * @version <pre>
 * Author     Version       Date        Changes
 * dinghua.an   1.0         2015年11月10日     Created
 *
 * </pre>
 * @since 1.
 */
public class WinitToolsProductFieldBuilder {

    /**
     * build 验货/提货信息
     * 
     * @param json
     * @return
     */
    public static ProductRecommendRequestParams buildRecommendRequestParams(JSONObject json) {
        ProductRecommendRequestParams params = new ProductRecommendRequestParams();
        params.seteBaySellerID(null == json.get("sellerID") ? null : json.getString("sellerID").trim());
        params.setValidationType(null == json.get("validationType") ? null : json.getString("validationType").trim());
        params.setWarehouseCode(null == json.get("warehouseCode") ? null : json.getString("warehouseCode").trim());
        params.setWinitProductCode(null == json.get("winitProductCode") ? null : json.getString("winitProductCode")
                .trim());
        
        Bpartner partner = CommandContext.getContext().get("apiBpartner");
        params.setCustomerCode(partner.getValue());

        RequestParamsReceiveAddress address = new RequestParamsReceiveAddress();
        JSONObject addressJson = (JSONObject) json.get("receiverAddress");
        if (null != addressJson) {
            address.setAddressLine1(null == addressJson.get("addressLine1") ? null : addressJson.getString(
                    "addressLine1").trim());
            address.setAddressLine2(null == addressJson.get("addressLine2") ? null : addressJson.getString(
                    "addressLine2").trim());
            address.setCity(null == addressJson.get("city") ? null : addressJson.getString("city").trim());
            address.setCountry(null == addressJson.get("country") ? null : addressJson.getString("country").trim());
            address.setEmail(null == addressJson.get("email") ? null : addressJson.getString("email").trim());
            address.setHouseNo(null == addressJson.get("houseNO") ? null : addressJson.getString("houseNO").trim());
            address.setName(null == addressJson.get("name") ? null : addressJson.getString("name").trim());
            address.setPhone(null == addressJson.get("phone") ? null : addressJson.getString("phone").trim());
            address.setPostCode(null == addressJson.get("postCode") ? null : addressJson.getString("postCode").trim());
            address.setState(null == addressJson.get("state") ? null : addressJson.getString("state").trim());
            params.setAddress(address);
        }

        if (null != json.get("parcels")) {
            JSONArray parcelsJsonArray = json.getJSONArray("parcels");
            List<RequestParamsParcels> parcels = new ArrayList<RequestParamsParcels>();
            for (Object parcelObj : parcelsJsonArray) {
                JSONObject parcelJson = (JSONObject) parcelObj;
                if (null == parcelJson.get("merchandiseInfos")
                        || parcelJson.getJSONArray("merchandiseInfos").size() == 0) {
                    throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "merchandiseInfos");
                }
                RequestParamsParcels parcel = new RequestParamsParcels();
                List<RequestParamsMerchandises> merchandises = new ArrayList<RequestParamsMerchandises>();
                JSONArray merchandisesJsonArray = parcelJson.getJSONArray("merchandiseInfos");
                for (Object merchandiseObj : merchandisesJsonArray) {
                    JSONObject merchandiseJson = (JSONObject) merchandiseObj;
                    RequestParamsMerchandises merchandise = new RequestParamsMerchandises();
                    merchandise.seteBayItemID((null == merchandiseJson.get("eBayItemID") || StringUtils
                            .isBlank(merchandiseJson.getString("eBayItemID"))) ? null : merchandiseJson.getString(
                            "eBayItemID").trim());
                    merchandise.seteBayTransactionID((null == merchandiseJson.get("eBayTransactionID") || StringUtils
                            .isBlank(merchandiseJson.getString("eBayTransactionID"))) ? null : merchandiseJson
                            .getString("eBayTransactionID").trim());
                    if (null == merchandiseJson.get("qty")) {
                        throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "qty");
                    } else {
                        merchandise.setQty(merchandiseJson.getIntValue("qty"));
                    }
                    merchandise.setSKU((null == merchandiseJson.get("SKU") || StringUtils.isBlank(merchandiseJson
                            .getString("SKU"))) ? null : merchandiseJson.getString("SKU").trim());
                    merchandise.setSpecification((null == merchandiseJson.get("specification") || StringUtils
                            .isBlank(merchandiseJson.getString("specification"))) ? null : merchandiseJson.getString(
                            "specification").trim());
                    merchandises.add(merchandise);
                }
                parcel.setMerchandises(merchandises);
                parcels.add(parcel);
            }
            params.setParcels(parcels);
        }
        
        if (json.containsKey("VASList")) {
            JSONArray vasArray = json.getJSONArray("VASList");
            List<RequestParamsVAS> vasList = new ArrayList<RequestParamsVAS>();
            for (Object vas : vasArray) {
                JSONObject obj = (JSONObject) vas;
                RequestParamsVAS vasParams = new RequestParamsVAS();
                vasParams.setCode(obj.getString("serviceCode"));
                JSONArray vasAttrArray = obj.getJSONArray("attrList");
                if(null==vasAttrArray||vasAttrArray.size()==0){
                    continue;
                }
                List<RequestParamsVASAttrs> paramAttrs = new ArrayList<RequestParamsVASAttrs>();
                for (Object attr : vasAttrArray) {
                    JSONObject attrObj = (JSONObject) attr;
                    RequestParamsVASAttrs paramAttr = new RequestParamsVASAttrs();
                    paramAttr.setAttrCode(attrObj.getString("attrCode"));
                    paramAttr.setAttrValue(attrObj.getString("attrValue"));
                    paramAttrs.add(paramAttr);
                }
                vasParams.setVasAttrs(paramAttrs);
                vasList.add(vasParams);
            }
            if (null != vasList && vasList.size() > 0) {
                params.setValueAddedServices(vasList);
            }
        }

        return params;
    }

    /**
     * 出参构建
     * 
     * @param result
     * @return
     */
    public static Map<String, Object> buildRecommendResult(ProductRecommendProductResult result) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("isEbayOrder", result.getIsEbayOrder());
        resultMap.put("isEGDOrder", result.getIsEGDOrder());
        resultMap.put("reason", result.getReason());
        if (null != result.getCurrentProduct()) {
            Map<String, Object> currentProductMap = new HashMap<String, Object>();
            currentProductMap.put("winitProductCode", result.getCurrentProduct().getWinitProductCode());
            currentProductMap.put("isUsable", result.getCurrentProduct().getIsUsable());
            resultMap.put("isGuarantee", result.getIsGuarantee());
            currentProductMap.put("estimateFee", result.getCurrentProduct().getEstimateFee());
            currentProductMap.put("currency", result.getCurrentProduct().getCurrency());
            currentProductMap.put("estimateDeliveryDate", result.getCurrentProduct().getEstimateDeliveryDate());
            currentProductMap.put("productDesc", result.getCurrentProduct().getProductDesc());
            resultMap.put("currentProduct", currentProductMap);
        }
        
        List<Map<String, Object>> products = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> unavailableProducts = new ArrayList<Map<String, Object>>();
        List<QueryUsableWinitProductResult> list=result.getResultList();
        if(null!=list&&list.size()>0){
            for(QueryUsableWinitProductResult productResult:list){
                Map<String, Object> map=buildWinitProduct(productResult);
                if("0".equals(productResult.getErrorCode())){
                    products.add(map);
                }else {
                    map.put("isUsable", "N");
                    unavailableProducts.add(map);
                }
            }
        }
        
        if (null != result.getWinitProdcuts() && result.getWinitProdcuts().size() > 0) {
            for (ResultWinitProduct product : result.getWinitProdcuts()) {
                Map<String, Object> productMap = new HashMap<String, Object>();
                productMap.put("winitProductCode", product.getWinitProductCode());
                productMap.put("estimateFee", product.getEstimateFee());
                productMap.put("currency", product.getCurrency());
                productMap.put("estimateDeliveryDate", product.getEstimateDeliveryDate());
                products.add(productMap);
            }
        }
        resultMap.put("recomendProduct", products);
        
        if (null != result.getUnavailableWinitProdcuts() && result.getUnavailableWinitProdcuts().size() > 0) {
            for (ResultWinitProduct product : result.getUnavailableWinitProdcuts()) {
                Map<String, Object> productMap = new HashMap<String, Object>();
                productMap.put("winitProductCode", product.getWinitProductCode());
                productMap.put("isUsable", product.getIsUsable());
                unavailableProducts.add(productMap);
            }
        }
        resultMap.put("unavailableProduct", unavailableProducts);
        return resultMap;
    }
    
    

    public static Map<String, Object> buildEGDValidatResult(Response response) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("failedCount", response.getFailedCount());
        return result;
    }

    /**
     * 构建产品费用列表
     * 
     * @param list
     * @return
     */
    private static Map<String, Object> buildWinitProduct(QueryUsableWinitProductResult item) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("currency", item.getCurrency());
        map.put("errorCode", item.getErrorCode());
        map.put("errorMsg", item.getErrorMsg());
        map.put("outboundType", item.getOutboundType());
        map.put("isUploadProductTicket", item.getIsUploadProductTicket());
        map.put("sla", item.getSla());
        map.put("estimateFee", item.getTotalAmount());
        map.put("length", item.getLength());
        map.put("width", item.getWidth());
        map.put("height", item.getHeight());
        map.put("weight", item.getWeight());
        map.put("volume", item.getVolume());
        map.put("trayCount", item.getTrayQty());
        map.put("winitProductCode", item.getWinitProductCode());
        map.put("winitProductName", item.getWinitProductName());
        map.put("EGDVldDescCode", item.getEGDVldDescCode());
        map.put("EGDVldDesc", item.getEGDVldDesc());
        map.put("EGDValidateCode", item.getEGDValidateCode());
        map.put("deliveryID", item.getDeliveryMode());//对接AD的派送ID
        map.put("estimateDeliveryDate", item.getEstimateCompleteDate());
        // 构建费用明细
        List<Map<String, Object>> feeList = new ArrayList<Map<String, Object>>();
        if (null != item.getFeeDetail() && item.getFeeDetail().size() > 0) {
            for (FeeDetailResult feeItem : item.getFeeDetail()) {
                Map<String, Object> feeMap = new HashMap<String, Object>();
                feeMap.put("amount", feeItem.getAmount());
                feeMap.put("chargeCode", feeItem.getChargeCode());
                feeMap.put("chargeName", feeItem.getChargeName());
                feeMap.put("currency", feeItem.getCurrency());
                feeMap.put("serviceCode", feeItem.getServiceCode());
                feeMap.put("serviceName", feeItem.getServiceName());
                feeList.add(feeMap);
            }
        }
        map.put("feeDetail", feeList);
        // 构建托盘明细
        List<Map<String, Object>> palletDetailList = new ArrayList<Map<String, Object>>();
        if (null != item.getPalletDetailList() && item.getPalletDetailList().size() > 0) {
            for (OutboundOrderPalletDetailVo palletDetailVo : item.getPalletDetailList()) {
                Map<String, Object> palletDetailMap = new HashMap<String, Object>();
                palletDetailMap.put("palletQty", palletDetailVo.getPalletQty());
                palletDetailMap.put("palletType", palletDetailVo.getPalletType());
                palletDetailMap.put("length", palletDetailVo.getPlLength());
                palletDetailMap.put("width", palletDetailVo.getPlWidth());
                palletDetailMap.put("height", palletDetailVo.getPlHeight());
                palletDetailList.add(palletDetailMap);
            }
        }
        map.put("palletDetail", palletDetailList);
        //增值服务明细
        List<VasInfo> valueAddedServiceList = item.getValueAddedServiceList();
        List<Map<String, Object>> valueAddedServiceMapList = new ArrayList<Map<String, Object>>();
        if (null != valueAddedServiceList && valueAddedServiceList.size() > 0) {
            for (VasInfo vo : valueAddedServiceList) {
                Map<String, Object> valueAddedServiceMap = new HashMap<String, Object>();
                valueAddedServiceMap.put("serviceCode", vo.getServiceCode());
                valueAddedServiceMap.put("serviceName", vo.getServiceName());
                List<VasAttributeInfo> attributeInfoList = vo.getAttributeInfoList();
                if (null != attributeInfoList && attributeInfoList.size() > 0) {
                    List<Map<String, Object>> attributeInfoMapList = new ArrayList<Map<String, Object>>();
                    for (VasAttributeInfo attributeInfo : attributeInfoList) {
                        Map<String, Object> attributeInfoMap = new HashMap<String, Object>();
                        attributeInfoMap.put("attrCode", attributeInfo.getAttributeKey());
                        attributeInfoMap.put("attrName", attributeInfo.getAttributeName());
                        attributeInfoMap.put("attrUnit", attributeInfo.getUnit());
                        attributeInfoMapList.add(attributeInfoMap);
                    }
                    valueAddedServiceMap.put("attrList", attributeInfoMapList);
                    //TODO 待确认
                    valueAddedServiceMap.put("ISOCode", "");
                    valueAddedServiceMap.put("FeeNumber", "");
                }
                valueAddedServiceMapList.add(valueAddedServiceMap);
            }
            map.put("VASFeeList", valueAddedServiceMapList);
        }
        return map;
    }
}
